package com.krystal.crawler;

import com.alibaba.fastjson.JSON;
import com.core.var.Constants;
import com.krystal.bean.CovidChinaBean;
import com.krystal.mapper.DataMapper;
import com.krystal.services.SpiderMsgService;
import com.krystal.util.HttpUtils;
import com.krystal.util.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Krystal1
 * @date 2021/4/25 -14:25
 * 实现covid19_1数据库表内容的爬取和传递 初始化和更新操作  该类爬取丁香园接口
 * <p>
 * 由于是过去的每一天的数据，所以每次更新需要手动更换请求json数据的url地址（地址在：https://ncov.dxy.cn/ncovh5/view/pneumonia）
 * F12查看网页元素 all标签下 **-62.json下的第一个**-135.json基本就是需要的接口地址了
 *
 * *注意： 这个更新的逻辑是建立在数据开始时间是20200119的  其他的数据会不准确 导致数据不会更新*********************************
 *
 */
@Slf4j
@Component
public class Covid19DateCrawlerCountry {
    private static DataMapper mapper;

    static {            //静态代码块初始化SqlSession工具
        InputStream resourceAsStream;
        try {
            resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            mapper = sqlSession.getMapper(DataMapper.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 抓取丁香园上的中国数据存入数据库中，返回更新多少条数据/返回信息      需要参数  ：网址
     * @since 2022/1/16 16:03:12
     * @return Response
     */
    public SpiderMsgService.Response crawlChinaData(SpiderMsgService.Request request){
        /**响应消息*/
        SpiderMsgService.Response response = new SpiderMsgService.Response();
        String url = request.getUrl();
        String datetime = TimeUtils.format(System.currentTimeMillis(), "yyyy-MM-dd");
        //1.爬取指定页面 返回json格式数据
        String html = HttpUtils.getHtml(url);
        //2.使用正则表达式获取json格式的疫情数据
        String pattern = "\\[(.*)\\]";              //定义正则规则
        Pattern reg = Pattern.compile(pattern);     //编译成正则对象
        Matcher matcher = reg.matcher(html);        //去text中进行匹配
        String jsonStr = "";
        if (matcher.find()) {                         //如果text中的内容和正则规则匹配上就取出来赋值给jsonStr变量
            jsonStr = matcher.group(0);
            log.info("json报文:{}",jsonStr);//爬取的报文
        } else {
            log.info("no match");
            response.setIsUpdated("0");
            response.setReturnMsg("正则表达式：no match");
            return  response;
        }
        //3.对json数据进行更进一步的解析
        List<CovidChinaBean> covidChinaBeans = JSON.parseArray(jsonStr, CovidChinaBean.class);
        log.info("爬取数据共{}条数据",covidChinaBeans.size());
        int currentCount = mapper.selectDataCountry(); //数据库中有的数据量
        log.info("数据库表covid19_1有{}条数据",currentCount);
        int updateCount = 0;//更新数据条数
        if (currentCount == 0) {            //数据库中没有数据那就直接全部添加
            log.info("数据库中没有数据那就直接全部添加");
            log.info("更新数据库中，请勿结束程序~");
            for (CovidChinaBean covidChinaBean : covidChinaBeans) {
                mapper.insertInitCountry(covidChinaBean);
                updateCount++;
            }
            log.info("更新数据完毕~");

            response.setIsUpdated("1");//更新成功
            response.setUpdateCount(updateCount+"");
            response.setReturnCode(Constants.SUCCESS_CODE);//000000
            response.setReturnMsg("本地数据插入成功!");
            return response;
        } else if (currentCount < covidChinaBeans.size()) {
            //如果数据库中的数据量小于获取到的数据量 则从数据库的最后一条数据开始添加
            log.info("更新数据库中，请勿结束程序~");
            for (int i = currentCount; i < covidChinaBeans.size(); i++) {
                CovidChinaBean covidChinaBean = covidChinaBeans.get(i);
                mapper.insertInitCountry(covidChinaBean);
                updateCount++;
            }
            response.setIsUpdated("1");//更新成功
            response.setUpdateCount(updateCount+"");
            response.setReturnCode(Constants.SUCCESS_CODE);//000000
            response.setReturnMsg("本地数据更新成功!");
            log.info("更新数据完毕~");
            return response;
        } else if (currentCount == covidChinaBeans.size()) {
            log.info("当前数据是最新数据，无需更新");
            response.setIsUpdated("0");
            response.setReturnMsg("当前数据是最新数据，无需更新");
            response.setReturnCode(Constants.NO_NEED_UPDATE);//100000
            return response;
        } else {
            log.info("数据库的数据比爬取的数据多，建议删除本地数据库该表数据，再执行爬虫！");
            response.setIsUpdated("0");
            response.setReturnMsg("数据库的数据比爬取的数据多，建议删除本地数据库该表数据，再执行爬虫！");
            response.setReturnCode(Constants.CRAWL_FAIL_CODE);//999998
            return response;
        }
    }



    /**测试类  弃用*/
    public static void main(String[] args) {
        String datetime = TimeUtils.format(System.currentTimeMillis(), "yyyy-MM-dd");
        //1.爬取指定页面 返回json格式数据
        String html = HttpUtils.getHtml("https://file1.dxycdn.com/2022/0116/819/3281690948332086253-135.json?t=27371983");
        //2.使用正则表达式获取json格式的疫情数据
        String pattern = "\\[(.*)\\]";              //定义正则规则
        Pattern reg = Pattern.compile(pattern);     //编译成正则对象
        Matcher matcher = reg.matcher(html);        //去text中进行匹配
        String jsonStr = "";
        if (matcher.find()) {                         //如果text中的内容和正则规则匹配上就取出来赋值给jsonStr变量
            jsonStr = matcher.group(0);
            //System.out.println(jsonStr);
        } else {
            System.out.println("no match");
        }
        //3.对json数据进行更进一步的解析
        List<CovidChinaBean> covidChinaBeans = JSON.parseArray(jsonStr, CovidChinaBean.class);
        int currentCount = mapper.selectDataCountry(); //数据库中有的数据量
        int updateCount = 0;
        if (currentCount == 0) {            //数据库中没有数据那就直接全部添加
            for (CovidChinaBean covidChinaBean : covidChinaBeans) {
                mapper.insertInitCountry(covidChinaBean);
                updateCount++;
            }
        } else if (currentCount < covidChinaBeans.size()) {      //如果数据库中的数据量小于获取到的数据量 则从数据库的最后一条数据开始添加
            for (int i = currentCount; i < covidChinaBeans.size(); i++) {
                CovidChinaBean covidChinaBean = covidChinaBeans.get(i);
                mapper.insertInitCountry(covidChinaBean);
                updateCount++;
            }
        } else if (currentCount == covidChinaBeans.size()) {
            log.info("当前数据是最新数据，无需更新");
            return;
        } else {
            log.info("数据库中的数据比获取到的数据多，可能数据异常");
            return;
        }
        log.info("数据更新完毕," + "本次更新" + updateCount + "条数据");
    }
}
